/*
 Servidor em java utilizando socket e implementado atravez da interface ObjetoDistribuido
 */

import java.net.*;
import java.io.*;
import tools.command.*;
import tools.canal.*;
import tools.ObjetoDistribuido.*;
import tools.command.commandInterface.*;

/**
 * @author rapha Class Cliente que sera executada nos celulares
 */
public class Cell extends ObjetoDistribuido implements Serializable {

	/**
	 * Declarações iniciais
	 */
	private static int port;
	private static Socket connection;
	private static String tipo, host;
	private static Cell celular;
	private static Canal canal;
	private static Command cmd;

	/*--------------------------------------	
	 *	   Implementação da interface 	
	 *	      Objeto distribuido							
	 --------------------------------------*/

	/*
	 * (non-Javadoc)
	 * 
	 * @see tools.ObjetoDistribuido.ObjetoDistribuido#usage() Implementação da
	 * função usage da interface ObjetoDistribuido
	 */
	public void usage() {
		System.out.println("Usage: \n $java socketClient host  port ");
		System.out.println("\t host: \t\t nome do host a se conectar");
		System.out.println("\t port: \t\t Porto a ser utilizado");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tools.ObjetoDistribuido.ObjetoDistribuido#getPort() retorna a porta
	 * que irá se conectar
	 */
	public int getPort() {
		return Cell.port;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tools.ObjetoDistribuido.ObjetoDistribuido#setPort(int) Seta qual
	 * porto deve ser utilizado
	 */
	public void setPort(int port) {
		Cell.port = port;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tools.ObjetoDistribuido.ObjetoDistribuido#setTipo(java.lang.String)
	 */
	public void setTipo(String tipo) {

		Cell.tipo = tipo;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tools.ObjetoDistribuido.ObjetoDistribuido#getTipo()
	 */
	public String getTipo() {

		return Cell.tipo;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see tools.ObjetoDistribuido.ObjetoDistribuido#fecha()
	 */
	public void fecha() {
		try {
			//Cell.connection.close();
			canal.closeConnection();

		} catch (Exception e) {

			System.out.println("Não consegui fechar a conexão");
			System.exit(0);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seetools.ObjetoDistribuido.ObjetoDistribuido#escreve(tools.command.
	 * commandInterface.Command)
	 */
	public void escreve(Command envio) {

		System.out.println("Socket iniciado para " + getHost() + " na porta "
				+ getPort());
		canal.escreve(envio);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seetools.ObjetoDistribuido.ObjetoDistribuido#recebe(tools.command.
	 * commandInterface.Command)
	 */
	public void recebe(Command cmd) {

		cmd = canal.recebe();
		executa(cmd, this);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seetools.ObjetoDistribuido.ObjetoDistribuido#executa(tools.command.
	 * commandInterface.Command)
	 */
	public void executa(Command cmd, ObjetoDistribuido celular) {

		cmd.executa(this);

	}

	/*--------------------------------------
	 *	         Funções próprias		
	--------------------------------------*/

	/**
	 * @param host
	 *            - endreço o qual deve se conectar
	 * @param porta
	 *            - Porto que será utilizado na conexão Construtor Parametrizado
	 */
	public Cell(String host, int porta) {
		setPort(porta);
		setHost(host);
		setTipo("client");
		
		// Instancia o canal
		canal = new Canal(host, porta);
		
		// incia connection no canal
		canal.openConnectionClient();

	}

	/**
	 * Construtor Default
	 */
	public Cell() {
		setPort(2222);
		setHost("localhost");
		setTipo("client");
		// Instancia o canal
		canal = new Canal("localhost", 2222);
		// incia connection no canal
		canal.openConnectionClient();
	}

	/**
	 * @return Endreço ao qual o client se conecta
	 */
	public String getHost() {
		return Cell.host;
	}

	/**
	 * @param host
	 *            - Endreço o qual o cliente se conectará
	 */
	public void setHost(String host) {
		Cell.host = host;
	}

	/**
	 * @param args
	 *            - Vetor de String contendo os parametros necessários Função
	 *            principal do client
	 */
	public static void main(String[] args) {

		// verifica se foram passados 3 parametros
		if (args.length != 2) {
			celular = new Cell();
			celular.usage();
		} else {



			// Instancia objeto client
			celular = new Cell(args[0], Integer.parseInt(args[1]));
			cmd = new CommandGetTipo();


			System.out.println("Celular iniciado");

			celular.escreve(cmd);

			//Afim apenas de comparar execuções
			cmd.executa(celular);

			// fecha connection
			celular.fecha();
		}

	}
}
